package com.bt7274.controller;


import com.bt7274.annotation.RequireLogin;
import com.bt7274.enums.AssessmentMetricType;
import com.bt7274.enums.AssessmentPenaltyType;
import com.bt7274.grace.result.GraceJSONResult;
import com.bt7274.pojo.bo.*;
import com.bt7274.pojo.vo.*;
import com.bt7274.service.AssessmentService;
import com.bt7274.utils.PageResponse;
import com.bt7274.utils.SessionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @BelongsProject: bt7274-back
 * @BelongsPackage: com.bt7274.controller
 * @Author: Galland
 * @CreateTime: 2025-06-14
 * @Description: TODO
 * @Version: 1.0
 */
@Tag(name = "用户考核管理")
@RestController
@RequestMapping("/api/assessment")
@RequiredArgsConstructor
public class AssessmentController {

    private final AssessmentService assessmentService;

    // ========== 用户接口 ==========

    @Operation(summary = "获取我的考核状态")
    @GetMapping("/my-status")
    @RequireLogin
    public GraceJSONResult getMyAssessmentStatus() {
        String userId = SessionUtils.getCurrentUserId();
        if (userId == null) {
            return GraceJSONResult.errorMsg("用户未登录");
        }
        UserAssessmentStatusVO status = assessmentService.getUserAssessmentStatus(userId);
        return GraceJSONResult.ok(status);
    }

    @Operation(summary = "获取我的考核历史")
    @GetMapping("/my-history")
    @RequireLogin
    public GraceJSONResult getMyAssessmentHistory(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
        String userId = SessionUtils.getCurrentUserId();
        if (userId == null) {
            return GraceJSONResult.errorMsg("用户未登录");
        }
        PageResponse<AssessmentResultVO> history =
                assessmentService.getUserAssessmentHistory(userId, current, size, startTime, endTime);
        return GraceJSONResult.ok(history);
    }

    @Operation(summary = "获取我的活跃惩罚")
    @GetMapping("/my-penalties")
    @RequireLogin
    public GraceJSONResult getMyActivePenalties() {
        String userId = SessionUtils.getCurrentUserId();
        if (userId == null) {
            return GraceJSONResult.errorMsg("用户未登录");
        }
        List<String> penalties = assessmentService.getUserActivePenalties(userId);
        return GraceJSONResult.ok(penalties);
    }

    // ========== 管理员接口 ==========

    @Operation(summary = "创建考核规则")
    @PostMapping("/admin/rule")
    @RequireLogin
    public GraceJSONResult createAssessmentRule(@Valid @RequestBody CreateUserRuleBO ruleBO) {
        Integer ruleId = assessmentService.createAssessmentRule(ruleBO);
        return GraceJSONResult.ok("考核规则创建成功");
    }

    @Operation(summary = "更新考核规则")
    @PutMapping("/admin/rule")
    @RequireLogin
    public GraceJSONResult updateAssessmentRule(@Valid @RequestBody UpdateUserRuleBO ruleBO) {
        assessmentService.updateAssessmentRule(ruleBO);
        return GraceJSONResult.ok("考核规则更新成功");
    }

    @Operation(summary = "删除考核规则")
    @DeleteMapping("/admin/rule/{ruleId}")
    @RequireLogin
    public GraceJSONResult deleteAssessmentRule(@PathVariable Integer ruleId) {
        assessmentService.deleteAssessmentRule(ruleId);
        return GraceJSONResult.ok("考核规则删除成功");
    }

    @Operation(summary = "启用/禁用考核规则")
    @PutMapping("/admin/rule/{ruleId}/toggle")
    @RequireLogin
    public GraceJSONResult toggleRuleStatus(
            @PathVariable Integer ruleId,
            @RequestParam Integer isActive) {
        assessmentService.toggleRuleStatus(ruleId, isActive);
        return GraceJSONResult.ok(isActive == 1 ? "规则已启用" : "规则已禁用");
    }

    @Operation(summary = "获取考核规则列表")
    @GetMapping("/admin/rules")
    @RequireLogin
    public GraceJSONResult getAssessmentRules(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) Integer isActive) {
        PageResponse<UserRuleVO> rules = assessmentService.getAssessmentRules(current, size, isActive);
        return GraceJSONResult.ok(rules);
    }

    @Operation(summary = "获取规则详情")
    @GetMapping("/admin/rule/{ruleId}")
    @RequireLogin
    public GraceJSONResult getRuleDetail(@PathVariable Integer ruleId) {
        UserRuleVO rule = assessmentService.getRuleDetail(ruleId);
        return GraceJSONResult.ok(rule);
    }

    @Operation(summary = "手动执行考核")
    @PostMapping("/admin/execute")
    @RequireLogin
    public GraceJSONResult executeManualAssessment(
            @RequestBody ManualAssessmentBO assessmentBO) {
        BatchAssessmentResultVO result = assessmentService.executeManualAssessment(assessmentBO);
        return GraceJSONResult.ok(result);
    }

    @Operation(summary = "考核单个用户")
    @PostMapping("/admin/assess-user")
    @RequireLogin
    public GraceJSONResult assessUser(
            @RequestParam String userId,
            @RequestParam(required = false) Integer ruleId) {
        List<AssessmentResultVO> results = assessmentService.assessUser(userId, ruleId);
        return GraceJSONResult.ok(results);
    }

    @Operation(summary = "获取用户考核状态（管理员）")
    @GetMapping("/admin/user-status/{userId}")
    @RequireLogin
    public GraceJSONResult getUserAssessmentStatus(
            @PathVariable String userId) {
        UserAssessmentStatusVO status = assessmentService.getUserAssessmentStatus(userId);
        return GraceJSONResult.ok(status);
    }

    @Operation(summary = "获取考核统计")
    @GetMapping("/admin/statistics")
    @RequireLogin
    public GraceJSONResult getAssessmentStatistics(
            @RequestParam(required = false) Integer ruleId,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
        List<AssessmentStatisticsVO> statistics =
                assessmentService.getAssessmentStatistics(ruleId, startTime, endTime);
        return GraceJSONResult.ok(statistics);
    }

    @Operation(summary = "执行考核惩罚")
    @PostMapping("/admin/penalty/apply")
    @RequireLogin
    public GraceJSONResult applyPenalty(
            @RequestParam String userId,
            @RequestParam String penalty,
            @RequestParam String reason) {
        boolean success = assessmentService.applyPenalty(userId, penalty, reason);
        return GraceJSONResult.ok(success ? "惩罚执行成功" : "惩罚执行失败");
    }

    @Operation(summary = "撤销考核惩罚")
    @PostMapping("/admin/penalty/revoke")
    @RequireLogin
    public GraceJSONResult revokePenalty(
            @RequestParam String userId,
            @RequestParam String penalty,
            @RequestParam String reason) {
        boolean success = assessmentService.revokePenalty(userId, penalty, reason);
        return GraceJSONResult.ok( success ? "惩罚撤销成功" : "惩罚撤销失败");
    }

    @Operation(summary = "计算用户指标值")
    @GetMapping("/admin/calculate-metric")
    @RequireLogin
    public GraceJSONResult calculateUserMetric(
            @RequestParam String userId,
            @RequestParam String metric) {
        Float value = assessmentService.calculateUserMetric(userId, metric);
        return GraceJSONResult.ok(value);
    }

    // ========== 通用接口 ==========

    @Operation(summary = "获取所有考核指标类型")
    @GetMapping("/metric-types")
    public GraceJSONResult getMetricTypes() {
        List<MetricTypeVO> types = Arrays.stream(AssessmentMetricType.values())
                .map(type -> {
                    MetricTypeVO vo = new MetricTypeVO();
                    vo.setKey(type.getMetricKey());
                    vo.setName(type.name());
                    vo.setDescription(type.getDescription());
                    return vo;
                })
                .collect(Collectors.toList());
        return GraceJSONResult.ok(types);
    }

    @Operation(summary = "获取所有惩罚类型")
    @GetMapping("/penalty-types")
    public GraceJSONResult getPenaltyTypes() {
        List<PenaltyTypeVO> types = Arrays.stream(AssessmentPenaltyType.values())
                .map(type -> {
                    PenaltyTypeVO vo = new PenaltyTypeVO();
                    vo.setName(type.name());
                    vo.setDescription(type.getDescription());
                    vo.setIsSevere(type.isSevere());
                    return vo;
                })
                .collect(Collectors.toList());
        return GraceJSONResult.ok(types);
    }
}
